/*
 * $Id$
 */
package corejs.parser;

import static corejs.JsTokenType.*;

import corejs.Token;
import corejs.expr.AdditionExpr;
import corejs.expr.AndExpr;
import corejs.expr.EqualsExpr;
import corejs.expr.Expression;
import corejs.expr.GreaterEqualThanExpr;
import corejs.expr.GreaterThanExpr;
import corejs.expr.LessEqualThanExpr;
import corejs.expr.LessThanExpr;
import corejs.expr.MultiplicationExpr;
import corejs.expr.NotEqualsExpr;
import corejs.expr.OrExpr;
import corejs.expr.RefinementExpr;
import corejs.expr.StrictEqualsExpr;
import corejs.expr.StrictNotEqualsExpr;
import corejs.expr.SubtractionExpr;

/**
 *
 * @author myang
 */
public class BinaryOperatorParser implements InfixParser {

   private int _precedence;
   private boolean _isRight;

   public BinaryOperatorParser(final int precedence) {
      this(precedence, false);
   }

   public BinaryOperatorParser(final int precedence, final boolean isRight) {
      _precedence = precedence;
      _isRight = isRight;
   }

   @Override
   public Expression expr(final PrattParser parser, 
                          final Expression left, final Token tk) {
      final Expression right = 
              parser.expr(_precedence - (_isRight ? 1 : 0));
      if (tk.is(PLUS)) {
         return new AdditionExpr(left, right);
      }
      else if (tk.is(MINUS)) {
         return new SubtractionExpr(left, right);
      }
      else if (tk.is(STAR)) {
         return new MultiplicationExpr(left, right);
      }
      else if (tk.is(AND)) {
         return new AndExpr(left, right);
      }
      else if (tk.is(OR)) {
         return new OrExpr(left, right);
      }
      else if (tk.is(DOT)) {
         return RefinementExpr.dot(left, right);
      }
      else if (tk.is(LT)) {
         return new LessThanExpr(left, right);
      }
      else if (tk.is(GT)) {
         return new GreaterThanExpr(left, right);
      }
      else if (tk.is(LE)) {
         return new LessEqualThanExpr(left, right);
      }
      else if (tk.is(GE)) {
         return new GreaterEqualThanExpr(left, right);
      }
      else if (tk.is(EQUAL)) {
         return new EqualsExpr(left, right);
      }
      else if (tk.is(NOT_EQUAL)) {
         return new NotEqualsExpr(left, right);
      }
      else if (tk.is(STRICT_EQUAL)) {
         return new StrictEqualsExpr(left, right);
      }
      else if (tk.is(STRICT_NOT_EQUAL)) {
         return new StrictNotEqualsExpr(left, right);
      }
      throw new ParseException("unknown operator:" + tk.text());
   }

   @Override
   public int getPrecedence() {
      return _precedence;
   }
   
}
